/**
 * PaymentController.java
 * 
 * Copyright@2015 OVT Inc. All rights reserved. 
 * 
 * 2015年12月22日
 */
package com.ovt.order.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ovt.common.model.JsonDocument;
import com.ovt.order.controller.response.PaymentServiceAPIResult;
import com.ovt.order.dao.contant.OrderState;
import com.ovt.order.dao.contant.DBConstants.TABLES.ALI_PAYMENT_LOG;
import com.ovt.order.dao.contant.PayConstants.ALIPAY_TRADE_STATUS;
import com.ovt.order.dao.vo.AliPaymentLog;
import com.ovt.order.dao.vo.Order;
import com.ovt.order.dao.vo.Payment;
import com.ovt.order.service.OrderService;
import com.ovt.order.service.PaymentLogService;
import com.ovt.order.service.PaymentService;
import com.ovt.order.service.alipay.AlipayNotify;
import com.ovt.order.service.exception.InvalidDataInputException;
import com.ovt.order.service.exception.ServiceErrorCode;
import com.ovt.order.service.exception.ServiceException;
import com.ovt.order.service.utils.StateChecker;

/**
 * PaymentController
 * 
 * @Author leo.liu
 * @Version 1.0
 * @See
 * @Since [OVT Cloud Platform]/[API] 1.0
 */
@Controller
@RequestMapping("/pay")
public class PaymentController
{
    @Autowired
    private PaymentService paymentService;

    @Autowired
    private PaymentLogService paymentLogService;

    @Autowired
    private OrderService orderService;

    @RequestMapping(method = RequestMethod.POST, value = "/alinotify")
    @ResponseBody
    public String aliNotify(HttpServletRequest request)
            throws ServiceException, IOException
    {
        Map<String, String> params = AlipayNotify.processNotifyParams(request
                .getParameterMap());

        if (AlipayNotify.verify(params))
        {
            AliPaymentLog aliPaymentLog = paymentLogService
                    .saveAliPaymentLog(params);
            Order order = orderService.queryOrderInfo(aliPaymentLog
                    .getOutTradeNo());

            String trade_status = params.get(ALI_PAYMENT_LOG.TRADE_STATUS);

            if (trade_status.equals(ALIPAY_TRADE_STATUS.FINISHED))
            {

            }
            else if (trade_status.equals(ALIPAY_TRADE_STATUS.SUCCESS))
            {
                checkAliNotifyParams(order, params);

                Payment payment = paymentService
                        .parseAlipayPayNotifyParams(params);
                payment.setPayLogId(aliPaymentLog.getId());
                paymentService.updatePayment(payment);

                orderService.setOrderState(order.getOrderNo(),
                        OrderState.ORDER_PAID);
            }

            return JsonDocument.STATE_SUCCESS;
        }
        else
        {
            return JsonDocument.STATE_FAILED;
        }

    }

    @RequestMapping(method = RequestMethod.GET, value = "/list")
    @ResponseBody
    public JsonDocument getPaymentList() throws ServiceException
    {
        List<Payment> paymentList = paymentService.getPaymentList();

        return new PaymentServiceAPIResult(paymentList);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/log/list")
    @ResponseBody
    public JsonDocument getAliPaymentLogList() throws ServiceException
    {
        List<AliPaymentLog> aliPaymentList = paymentLogService
                .getAliPaymentLogList();

        return new PaymentServiceAPIResult(aliPaymentList);
    }

    private void checkAliNotifyParams(Order order, Map<String, String> params)
            throws ServiceException
    {
        if (order == null)
        {
            throw new InvalidDataInputException(
                    ServiceErrorCode.INVALID_ORDER_NUMBER,
                    "Invalid order number");
        }

        if (StateChecker.checkStateChangeValid(order.getOrderState(),
                OrderState.ORDER_PAID))
        {
            throw new InvalidDataInputException(
                    ServiceErrorCode.INVALID_ORDER_STATE, "Invalid order state");
        }

        if (order.getOrderTotalFee() != Float.valueOf(params
                .get(ALI_PAYMENT_LOG.TOTAL_FEE)))
        {
            throw new InvalidDataInputException(
                    ServiceErrorCode.INVALID_TOTAL_FEE, "Invalid total fee");
        }
    }
}
